package com.tian.service.impl;

import com.tian.dto.*;
import com.tian.enums.ResultCode;
import com.tian.enums.UserPointRecordTypeEnum;
import com.tian.feign.UserFeignClient;
import com.tian.message.UserPointMessage;
import com.tian.mq.UserPointInitProducer;
import com.tian.mq.UserProducer;
import com.tian.service.SendCodeService;
import com.tian.service.UserService;
import com.tian.util.CommonResult;
import com.tian.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;

/**
 * @author tianwc  公众号：java后端技术全栈、面试专栏
 * @version 1.0.0
 * @date 2023年05月11日 18:45
 * 博客地址：<a href="http://woaijava.cc/">博客地址</a>
 */
@Slf4j
@Service
@Scope(scopeName = "prototype")
public class UserServiceImpl implements UserService {
    @Resource
    private SendCodeService sendCodeService;
    @Resource
    private UserFeignClient userFeignClient;
    @Resource
    private UserPointInitProducer userPointInitProducer;
    @Resource
    private UserProducer userProducer;

    @Override
    public CommonResult<UserLoginResDto> login(SendCodeReqDto sendCodeReqDto, String codeCachePre) {
        if (paramCheckFailed(sendCodeReqDto)) {
            return CommonResult.failed(ResultCode.PARAMETER_EMPTY);
        }
        //验证码错误次数限流
        CommonResult<Boolean> sendResult = sendCodeService.codeValid(sendCodeReqDto.getPhone(), sendCodeReqDto.getCode(), codeCachePre);
        //验证码错误
        if (!sendResult.getData()) {
            return CommonResult.failed(sendResult.getMessage());
        }
        QueryUserReqDto queryUserReqDto = new QueryUserReqDto();
        queryUserReqDto.setPhone(sendCodeReqDto.getPhone());
        //用户信息
        CommonResult<QueryUserRespDto> queryUserRespDtoCommonResult = userFeignClient.findByPhone(queryUserReqDto);
        if (queryUserRespDtoCommonResult.getCode() != ResultCode.SUCCESS.getCode()) {
            return CommonResult.failed(ResultCode.PARAMETER_ERROR);
        }

        QueryUserRespDto queryUserRespDto = queryUserRespDtoCommonResult.getData();
        UserLoginResDto userLoginResDto = new UserLoginResDto();
        userLoginResDto.setUserId(queryUserRespDto.getId());
        userLoginResDto.setUserName(queryUserRespDto.getUserName());
        return CommonResult.success(userLoginResDto);
    }

    @Override
    public CommonResult<Boolean> register(RegisterReqDto registerReqDto, String codeCachePre) {
        CommonResult<Boolean> sendResult = sendCodeService.codeValid(registerReqDto.getPhone(), registerReqDto.getCode(), codeCachePre);
        //验证码错误
        if (!sendResult.getData()) {
            return CommonResult.failed(sendResult.getMessage());
        }
        CommonResult<Long> commonResult = userFeignClient.register(registerReqDto);
        if (commonResult.getCode() != ResultCode.SUCCESS.getCode()) {
            log.info("用户userId={}注册成功,使用的邀请码是{}", commonResult.getData(), registerReqDto.getCode());

            //异步初始化积分账户
            UserPointMessage userPointMessage = new UserPointMessage();
            userPointMessage.setPoints(5);
            userPointMessage.setUserId(commonResult.getData());
            userPointMessage.setType(UserPointRecordTypeEnum.ADD.getType());
            userPointInitProducer.initUserPoint(userPointMessage);

            //异步生成邀请记录、邀请收益流水、邀请人可用余额增加
            InvitedDto invitedDto = new InvitedDto();
            invitedDto.setInvitedCode(registerReqDto.getCode());
            //todo 可以做成配置化
            invitedDto.setIncome(new BigDecimal("100"));
            invitedDto.setUserId(commonResult.getData());
            invitedDto.setCreateTime(new Date());
            userProducer.invitedRegister(invitedDto);
            return CommonResult.success();
        }
        return CommonResult.failed("注册失败");
    }

    private boolean paramCheckFailed(SendCodeReqDto sendCodeReqDto) {
        return sendCodeReqDto == null || StringUtil.isBlank(sendCodeReqDto.getCode()) || StringUtil.isBlank(sendCodeReqDto.getPhone());
    }
}
